<script setup>
import {ref} from 'vue'
import {storeToRefs} from "pinia";
import {VueFlow, Position, useVueFlow} from '@vue-flow/core'

import CommandNode from './components/CommandNode.vue'
import BreakerNode from './components/BreakerNode.vue'

import SpecialEdge from './components/SpecialEdge.vue'
import Control from "@/views/process/Control.vue";
import CheckerNode from "@/views/process/components/CheckerNode.vue";
import {useUserProfile} from "@/stores/useUserProfile.js";

const {addNodes, addEdges, dimensions, toObject, fromObject, nodes, findNode} = useVueFlow()


const {profile} = storeToRefs(useUserProfile())
const initialNodes = ref([
	// 不同类型类型对应不同组件(指令器, 判定器, 暂停器)
	{
		id: '1',
		type: 'command',
		position: {x: 0, y: 60},

		data: {
			label: '指令器',
			sourcePosition: Position.Right,
			targetPosition: Position.Left
		},
	},
	{
		id: '2',
		type: 'checker',
		position: {x: 125, y: 250},
		targetPos: Position.Right,
		data: {
			label: '判定器',
			checkerList: [],
			sourcePosition: Position.Right,
			targetPosition: Position.Left
		},
	},
	{
		id: '3',
		type: 'breaker',
		position: {x: 250, y: 375},
		targetPos: Position.Right,
		data: {
			label: '暂停器',
			sourcePosition: Position.Right,
			targetPosition: Position.Left
		},
	}
])
// todo: 通过edge来映射执行顺序和走向, 通过拿到next来判断此时该做什么(执行指令, 暂停, 等待条件完成)
const edges = ref([
	{
		id: 'e1->2',
		source: '1',
		target: '2',
	},
	{
		id: 'e2->3',
		source: '2',
		target: '3',
		animated: true,
	},
	{
		id: 'e3->4',
		source: '3',
		target: '4',
		data: {
			hello: 'world',
		}
	},
])
const nodeTypeMap = {
	command: {
		label: "指令器",
	},
	checker: {
		label: "检查器",
	},
	breaker: {
		label: "暂停器"
	},
}

const onAddNode = (nodeType) => {
	console.log(initialNodes.value.length)
	// 向流程中加入节点
	let lastNodeIndex = initialNodes.value.length - 1
	let lastEdgeIndex = edges.value.length - 1
	// todo:优化加入逻辑, 计算父元素占比, 如果某个x坐标溢出父元素则调整y
	let node = {
		id: `${parseInt(initialNodes.value[lastNodeIndex].id) + 1}`,
		type: nodeType,
		position: {
			x: initialNodes.value[lastNodeIndex].position.x + 10,
			y: initialNodes.value[lastNodeIndex].position.y + 250,
		},
		data: {
			label: nodeTypeMap[nodeType].label,
			sourcePosition: Position.Right, targetPosition: Position.Left
		},
	}
	addNodes([node])
	initialNodes.value.push(node); // 同时更新本地维护的节点
	console.log(node)
	let edge = {
		id: `e${edges.value[lastEdgeIndex].target}->${parseInt(edges.value[lastEdgeIndex].target) + 1}`,
		type: 'special',
		source: `${parseInt(edges.value[lastEdgeIndex].source) + 1}`,
		target: `${parseInt(edges.value[lastEdgeIndex].target) + 1}`,
	}
	addEdges([edge])
	edges.value.push(edge)
	console.log(edge)
}
const removeNode = (nodeId) => {
	// 找到该节点
	const nodeToRemove = initialNodes.value.find((node) => node.id === nodeId);
	if (nodeToRemove) {
		// 删除与该节点相关的连线
		edges.value = edges.value.filter(
			(edge) => edge.source !== nodeId && edge.target !== nodeId
		);

		// 查找左右的节点并重新连接
		const leftNode = initialNodes.value.find(
			(node) => node.id === nodeToRemove.id && node.data.targetPosition === Position.Left
		);
		const rightNode = initialNodes.value.find(
			(node) => node.id === nodeToRemove.id && node.data.targetPosition === Position.Right
		);

		// 确保左节点连接右节点 (如果节点间确实需要连接)
		if (leftNode && rightNode) {
			edges.value.push({
				id: `e${leftNode.id}->${rightNode.id}`,
				source: leftNode.id,
				target: rightNode.id,
			});
		}

		// 删除该节点
		initialNodes.value = initialNodes.value.filter((node) => node.id !== nodeId);
	}
};

// 当前节点位置
const currentNodeIndex = ref(1)

/**
 * 执行全部节点的run方法
 */
/**
 * 执行全部节点的run方法
 */
const startTask = async () => {
    while (currentNodeIndex.value <= nodes.value.length) {
        // 执行任务
        await nextTask(currentNodeIndex.value.toString())
        // 设置状态
        currentNodeIndex.value += 1
    }
}

const nextTask = async (nodeId) => {
    console.log(nodeId, findNode(nodeId))
    const node = findNode(nodeId)
    node.data.execuated = true
    if (node.type === "command") {
        node.data.callback(node, profile.value.tabList)
    } else if (node.type === "checker") {
        // 在这里，我们可以等待子组件的判据检查通过
        await node.data.callback(node)
    }
}

// todo: 启动任务 -> 遍历所有节点的行为 -> 执行每个节点的行为
import {Panel} from '@vue-flow/core'

onMounted(() => {
	function onRestore() {
		const flow = JSON.parse(localStorage.getItem('vue-flow--save-restore'))

		if (flow) {
			fromObject(flow)
		}
	}

	// 每次初始化时恢复节点状态
	onRestore()
})
</script>

<template>
	<VueFlow class="mt-2 bg-zinc-900 w-full"
			 :nodes="initialNodes" :edges="edges"
			 :min-zoom="0.5" :max-zoom="20" :default-viewport="{zoom:0.4}" :fit-view="false">
		<Panel position="top-left">
			<n-space class="w-fit h-fit">
				<n-button type="info" @click="() => onAddNode('command')">加入指令器</n-button>
				<n-button type="success" @click="() => onAddNode('checker')">加入判定器</n-button>
				<n-button type="warning" @click="() => onAddNode('breaker')">加入暂停器</n-button>
				<n-button type="default" @click="console.log(nodes)">看节点</n-button>
				<n-button type="default" @click="startTask">看节点</n-button>
			</n-space>
		</Panel>
		<Control/>
		<!--指令器节点-->
		<template #node-command="CommandNodeProps">
			<CommandNode v-bind="CommandNodeProps" ref="commandNode"/>
		</template>

		<!--检查器节点-->
		<template #node-checker="checkerNodeProps">
			<CheckerNode v-bind="checkerNodeProps" ref="checkerNode"/>
		</template>

		<!--中断器节点-->
		<template #node-breaker="breakerNodeProps">
			<BreakerNode v-bind="breakerNodeProps" ref="breakerNode"/>
		</template>


		<template #edge-special="specialEdgeProps">
			<SpecialEdge v-bind="specialEdgeProps"/>
		</template>
	</VueFlow>

</template>

<style scoped>
/* import the necessary styles for Vue Flow to work */
@import '@vue-flow/core/dist/style.css';

/* import the default theme, this is optional but generally recommended */
@import '@vue-flow/core/dist/theme-default.css';

</style>